import com.powerfl.frm.taf.*;

static private function VARIABLE( $value:String, $variables:Object ):*{
	var temp:Array, result:*, i:int, j:int, k:int, l:int;
	if( $variables === null ){
		SELF.error( '참조 객체가 주어지지 않았습니다. - ' + $value );
	}
	temp = $value.split( '.' );
	result = $variables;
	for( i = 0, j = temp.length ; i < j ; ++i ){
		temp[i] = trim( temp[i] );
		k = temp[i].indexOf( '()' );
		l = temp[i].indexOf( '[' );
		if( temp[i] === 'this' ){
			temp[i] = $variables;
		}else if( k > -1 ){
			result = result[temp[i].substring( 0, k )]();
		}else if( l > -1 ){
			result = result[temp[i].substring( 0, l )][temp[i].substring( l, temp[i].indexOf( ']' ) )];
		}else{
			result = result[temp[i]];
		}
	}
	return result;
}
static public function EXPRESSION( $value:String, $variables:Object = null ):Number{
	var result:Number, i:int, j:int, k:int, val:Number, temp:Array, brit:Array, sval:String, key:*;
	
	$value = trim( $value );
	if( $value.search( rxUINT ) > -1 ){
		return uint( $value );
	}else if( $value.search( rxVARIABLE ) > -1 ){
		return VARIABLE( $value, $variables );
	}else if( $value.search( rxNUMBER ) > -1 ){
		return Number( $value );
	}else if( $value.search( rxBrit ) > -1 ){
		brit = [];
		while ( ( temp = rxBrit.exec( $value ) ) !== null ){
			brit.push( temp[2] );
			$value = $value.replace( temp[0], '$$BRIT' + ( brit.length - 1 ).toString() );
		}
		for( i = 0, j = brit.length ; i < j ; ++i ){
			brit[i] = brit[i].replace( rxGetBrit, function():String{
				return brit[arguments[2]];
			} );
			brit[i] = EXPRESSION( brit[i], $variables );
		}
		return EXPRESSION( 
			$value.replace( rxGetBrit, function():String{
				return brit[arguments[1]];
			} ), $variables
		);
	}
	temp = [];
	for( i = 0, j =  $value.length - 1, k = 0 ; i < j ; ++i ){
		if( $value.charAt( i ).search( rxExpression ) > -1 ){
			sval = $value.substring( k, i );
			if( sval === '' ){
				temp[temp.length] = 0;
			}else{
				temp[temp.length] = EXPRESSION( sval, $variables );
			}
			temp[temp.length] = $value.charAt( i );
			k = i + 1;
		}
	}
	temp[temp.length] = EXPRESSION( $value.substr( k ), $variables );
	
	for( i = 1 ; i < temp.length ; ++i ){
		switch( temp[i] ){
		case'~':
			temp.splice( i - 1, 3, TAF.SELF.mathRand( temp[i-1], temp[i+1] ) );
			--i;
			break;
		case'~N':
			temp.splice( i - 1, 3, TAF.SELF.mathRandN( temp[i-1], temp[i+1] ) );
			--i;
			break;
		case'~U':
			temp.splice( i - 1, 3, TAF.SELF.mathRandU( temp[i-1], temp[i+1] ) );
			--i;
			break;
		}
	}
	for( i = 1 ; i < temp.length ; ++i ){
		switch( temp[i] ){
		case'<<':
			temp.splice( i - 1, 3, temp[i-1] << temp[i+1] );
			--i;
			break;
		case'>>':
			temp.splice( i - 1, 3, temp[i-1] >> temp[i+1] );
			--i;
			break;	 
		}
	}
	for( i = 1 ; i < temp.length ; ++i ){
		if( temp[i] === '^' ){
			if( temp[i+1] ){
				val = 1;
				while( temp[i+1]-- ){
					val *= temp[i-1];
				}
			}else{
				val = 0;
			}
			temp.splice( i - 1, 3, val );
			--i;
			break;
		}
	}
	for( i = 1 ; i < temp.length ; ++i ){
		switch( temp[i] ){
		case'*':
			temp.splice( i - 1, 3, temp[i-1] * temp[i+1] );
			--i;
			break;
		case'/':
			temp.splice( i - 1, 3, temp[i-1] / temp[i+1] );
			--i;
			break;	 
		}
	}
	for( i = 1 ; i < temp.length ; ++i ){
		if( temp[i] === '%' ){
			temp.splice( i - 1, 3, temp[i-1] % temp[i+1] );
			--i;
			break;
		}
	}
	for( i = 1 ; i < temp.length ; ++i ){
		switch( temp[i] ){
		case'+':
			temp.splice( i - 1, 3, temp[i-1] + temp[i+1] );
			--i;
			break;
		case'-':
			temp.splice( i - 1, 3, temp[i-1] - temp[i+1] );
			--i;
			break;
		}
	}
	val = temp[0];
	for( i = 1 ; i < temp.length ; i += 2 ){
		switch( temp[i] ){
		case'+':
			val += temp[i+1];
			break;
		case'-':
			val -= temp[i+1];
			break;	 
		}
	}
	return val;
}